﻿using FlexFlow.Common;
using FlexFlow.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FlexFlow.Runtime
{
    /// <summary>
    /// 用户管理器，用来统一管理用户的注册，登录，登出，以及信息更新操作
    /// </summary>
    public class UserManager : ManagerBase
    {
        /// <summary>
        /// 获取或设置引擎默认的用户管理器
        /// </summary>
        public static UserManager Default { get; set; }
        /// <summary>
        /// 获取或设置用户管理器的默认用户密码
        /// </summary>
        public static string DefaultPassword { get; set; }
        /// <summary>
        /// 登录用户
        /// </summary>
        /// <param name="account">
        /// 用来登录的账户名
        /// </param>
        /// <param name="forcedLogin">
        /// 表示当前登录是否为强制登录，当使用强制登录时会忽略IP校验并且替换登录信息，
        /// 之前的登录将会失效
        /// </param>
        /// <param name="password">
        /// 用来登录的密码
        /// </param>
        /// <returns>
        /// 操作结果，若成功则其Tag为登录生成的Identity
        /// </returns>
        public OperateResult Login(string account, string password, bool forcedLogin)
        {
            OperateRunner runner = new OperateRunner();
            User user = this.Components.UserProvider.Get(account);
            if (user == null)
            {
                return new OperateResult()
                {
                    ResultCode = 0x010101,
                    Message = "用户不存在！"
                };
            }
            if (user.Password != password)
            {
                return new OperateResult()
                {
                    ResultCode = 0x010102,
                    Message = "用户名密码不匹配！"
                };
            }
            if (user.Locked)
            {
                return new OperateResult()
                {
                    ResultCode = 0x010103,
                    Message = "用户被锁定，无法登录！"
                };
            }

            //验证用户是否已经登录
            OnlineUserInfoHolder loginedUser = this.Components.OnlineUserPool.FirstOrDefault(m => m.LoginedUser.UserId == user.Identity);
            if (loginedUser != null)
            {
                if (!forcedLogin)
                {
                    return new OperateResult()
                    {
                        ResultCode = 0x010104,
                        Message = "用户已在 " + loginedUser.LoginedUser.IP + " 处登录！"
                    };
                }
                else
                {
                    if (!Logout(loginedUser))
                    {
                        return new OperateResult()
                        {
                            ResultCode = 0x010105,
                            Message = "注销别处登录失败！可能用户未在其它区域登录，请去除强制登录选项后重试！"
                        };
                    }
                }
            }
            //TODO:其它用户登录验证

            //登录用户
            loginedUser = new OnlineUserInfoHolder()
            {
                LastOperateTime = DateTime.Now,
                LoginedUser = new LoginedUserInfo()
                {
                    IP = Toolkit.GetClientIp(),
                    LoginTime = DateTime.Now,
                    Name = user.Name,
                    OrganizeName = user.OrganizeName,
                    OrganizationId = user.Organization,
                    UserId = user.Identity,
                    Tag = forcedLogin ? "登录" : "强制登录"
                }
            };
            this.Components.OnlineUserPool.Add(loginedUser);

            //验证成功
            return OperateResult.SuccessResult(loginedUser.LoginedUser.Identity);

        }
        /// <summary>
        /// 检测具有指定标识符的用户信息是否存在
        /// </summary>
        /// <param name="infoIdentity">
        /// 用来检测的用户信息
        /// </param>
        /// <returns>
        /// 检测结果
        /// </returns>
        public OperateResult CheckUserLogined(Guid infoIdentity)
        {
            //尝试取得登录信息
            OnlineUserInfoHolder info = this.Components.OnlineUserPool.FirstOrDefault(m => m.LoginedUser.Identity == infoIdentity);
            //判断指定登录信息是否存在
            if (info == null)
            {
                return OperateResult.SuccessResult(false);
            }
            else
            {
                info.LastOperateTime = DateTime.Now;
                return OperateResult.SuccessResult(true);
            }
        }
        /// <summary>
        /// 登出指定用户信息
        /// </summary>
        /// <param name="info">
        /// 要登出的用户信息
        /// </param>
        /// <returns>
        /// 若用户成功登出则为true，否则为false
        /// </returns>
        private bool Logout(OnlineUserInfoHolder info)
        {
            return this.Components.OnlineUserPool.Remove(info);
        }
        /// <summary>
        /// 登出用户
        /// </summary>
        /// <param name="infoId">
        /// 要登出的用户的在线信息Id
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        public OperateResult Logout(Guid infoId)
        {
            //验证用户是否已经登录
            OnlineUserInfoHolder loginnedUser = this.Components.OnlineUserPool.FirstOrDefault(m => m.LoginedUser.Identity == infoId);
            if (loginnedUser == null)
            {
                return new OperateResult()
                {
                    ResultCode = 0x010201,
                    Message = "指定的InfoId无效！"
                };
            }
            //尝试登出
            if (!Logout(loginnedUser))
            {
                return new OperateResult()
                {
                    ResultCode = 0x010202,
                    Message = "指定用户已登出！"
                };
            }

            //TODO:其它登出验证

            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 注册具有指定用户名与密码的用户
        /// </summary>
        /// <param name="account">
        /// 要注册的用户名
        /// </param>
        /// <param name="password">
        /// 要注册的密码
        /// </param>
        /// <returns>
        /// 注册的结果
        /// </returns>
        public OperateResult Register(string account, string password, string email)
        {
            //验证用户名是否已经存在
            if (this.Components.UserProvider.CheckAccountExisted(account))
            {
                return new OperateResult()
                {
                    ResultCode = 0x010301,
                    Message = "用户名已存在！"
                };
            }

            //验证Email是否已被注册
            if (this.Components.UserProvider.CheckEmailExisted(email))
            {
                return new OperateResult()
                {
                    ResultCode = 0x010302,
                    Message = "Email已被注册！"
                };
            }

            //TODO:其它注册验证

            //尝试注册
            User user = this.Components.UserProvider.Create();
            user.Account = account;
            user.Password = password;
            user.Email = email;

            this.Components.UserProvider.Add(user);

            //返回结果
            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 重命名指定用户
        /// </summary>
        /// <param name="identity">
        /// 用户ID
        /// </param>
        /// <param name="newName">
        /// 新名称
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        public OperateResult Rename(Guid identity, string newName)
        {
            bool res = this.Components.UserProvider.Rename(identity, newName);
            if (!res)
            {
                return new OperateResult()
                {
                    ResultCode = 0x010401,
                    Message = "重命名失败！"
                };
            }

            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 取得具有指定Guid的用户实体
        /// </summary>
        /// <param name="account">
        /// 用来取得实体的用户名
        /// </param>
        /// <returns>
        /// 取得的用户实体，若实体不存在，则返回null
        /// </returns>
        public OperateResult Get(Guid id)
        {
            User u = this.Components.UserProvider.Get(id);
            if (u == null)
            {
                return new OperateResult()
                {
                    ResultCode = 0x010501,
                    Message = "用户不存在或已被删除！"
                };
            }

            return OperateResult.SuccessResult(u);
        }
        /// <summary>
        /// 更新用户信息
        /// </summary>
        /// <param name="identity">
        /// 要更新的用户的ID
        /// </param>
        /// <param name="name">
        /// 新名称
        /// </param>
        /// <param name="account">
        /// 新账号
        /// </param>
        /// <param name="email">
        /// 新Email
        /// </param>
        /// <param name="isLock">
        /// 是否锁定
        /// </param>
        /// <returns>
        /// 一个表示更新是否成功的值
        /// </returns>
        public OperateResult Update(Guid identity, string name = null, string account = null, string email = null, bool? isLock = null)
        {
            if (!this.Components.UserProvider.Update(identity, name, account, email, isLock))
            {
                return new OperateResult()
                {
                    ResultCode = 0x010601,
                    Message = "数据更新失败！"
                };
            }

            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 更改指定用户的密码
        /// </summary>
        /// <param name="identity">
        /// 要更改密码的用户ID
        /// </param>
        /// <param name="newPwd">
        /// 要更改的新密码
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        public OperateResult ChangePassword(Guid identity, string newPwd = null)
        {
            if (!this.Components.UserProvider.ChangePassword(identity, newPwd == null ? DefaultPassword : newPwd))
            {
                return new OperateResult()
                {
                    ResultCode = 0x010701,
                    Message = "更改密码失败！"
                };
            }

            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 通过用户姓名查询用户信息(Like模糊查询)
        /// </summary>
        /// <param name="nameLike">
        /// 要查询的用户姓名
        /// </param>
        /// <param name="limit">
        /// 返回结果的限制数量
        /// </param>
        /// <param name="skip">
        /// 返回结果的起始位置
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        public OperateResult QueryUserByName(string nameLike, int skip = 0, int limit = 10)
        {
            if (limit > 50 || limit <= 0)
            {
                return new OperateResult()
                {
                    ResultCode = 0x010801,
                    Message = "limit必须在1-50之间！"
                };
            }

            return OperateResult.SuccessResult(this.Components.UserProvider.QueryByName(nameLike, skip, limit));
        }
        /// <summary>
        /// 初始化用户管理器的默认设置
        /// </summary>
        static UserManager()
        {
            Default = new UserManager();
            DefaultPassword = "123456789";
        }

    }
}
